﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;

    public class RuleStream : BaseStream
    {
        public RuleStream()
        {
            
        }
        public virtual AdvRuleKey ReadKey()
        {
            return (AdvRuleKey)ReadInt();
        }
        public virtual void Write(AdvRuleKey key)
        {
            Write((int)key);
        }
        /// <summary>
        /// 按照目录结构存储
        /// </summary>
        /// <param name="keys"></param>
        /// <param name="dates"></param>
        public virtual void WriteIndex(List<AdvRuleKey> keys, List<byte[]> dates)
        {
            int dataAddress = keys.Count * 8 + 4;//计算数据地址，{key+地址}+ 结束key
            int length = dataAddress + dates.Sum(s => s.Length + 4);
            Write(length);    //写入数据总长度
            for (int i = 0; i < keys.Count; i++)
            {
                dataAddress += i == 0 ? 0 : (dates[i - 1].Length + 4);//数据地址

                Write(keys[i]);
                Write(dataAddress);
            }
            Write(AdvRuleKey.End);//目录结束
            for (int i = 0; i < dates.Count; i++)
            {
                Write(dates[i].Length);     //数据长度
                Write(dates[i]);            //数据
            }
            Flush();
        }

        public virtual void ReadIndex(out List<AdvRuleKey> keys, out List<byte[]> dates)
        {
            RuleStream stream = new RuleStream();
            int length = ReadInt();     //读入流长度
            byte[] buffer = ReadBytes(length); //读入流数据
            stream.Write(buffer);
            stream.Seek(0, SeekOrigin.Begin);

            int currentAddress;
            int dataAddress;
            AdvRuleKey key;

            keys = new List<AdvRuleKey>();
            dates = new List<byte[]>();
            while ((key = stream.ReadKey()) != AdvRuleKey.End)
            {
                keys.Add(key);
                dataAddress = stream.ReadInt();
                currentAddress = (int)stream.Position;
                stream.Seek(dataAddress, SeekOrigin.Begin);
                dates.Add(stream.ReadBytes(stream.ReadInt()));
                stream.Seek(currentAddress, SeekOrigin.Begin);
            }
            stream.Close();
        }
    }
